<template>
  <div class="w-full h-full flex flex-col">
    <div
      class="w-full flex-1 my-[12px] min-h-0"
      @touchstart="hdlTouchStart"
      @touchmove="hdlTouchMove"
      @touchend="hdlTouchEnd"
    >
      <Carousel
        v-if="refresh"
        class="relative w-full h-full"
        ref="carousel_ref"
        :opts="{
          startIndex: currentIndex,
          loop: false,
        }"
        @init-api="setApi"
      >
        <CarouselContent>
          <CarouselItem v-for="(item, index) in contentList" :key="index">
            <div class="w-full h-full flex items-center px-[24px] pic-wrap">
              <img
                :src="item.media"
                class="h-full object-contain mx-auto pic"
              />
            </div>
          </CarouselItem>
        </CarouselContent>
      </Carousel>
    </div>
    <div
      v-if="platformList.length > 1"
      class="max-w-[228px] flex items-center justify-between mx-auto mb-[16px] border-solid border-[#f5f5f6] border rounded-[8px] overflow-hidden"
    >
      <div v-for="(plat, index) of platformList" :key="index">
        <button
          class="w-[76px] h-[32px] text-[#666666] text-[12px] font-[400]"
          :class="{
            'bg-[#F5F5F6]': platform === plat,
          }"
          @click="changePlatform(plat)"
        >
          {{ plat }}
        </button>
        <div
          class="w-[1px] h-full bg-[#f5f5f6]"
          v-if="index < platformList.length - 1"
        ></div>
      </div>
    </div>
    <div
      ref="markdown_ref"
      class="w-full h-[150px] shrink-0 overflow-y-auto"
      v-if="refresh"
    >
      <div v-html="compiledMarkdown" class="md-style px-[32px]"></div>
    </div>
    <div class="w-full h-[20px] flex items-center justify-center">
      <div
        class="w-[6px] h-[6px] rounded-full"
        v-for="(_, index) in contentList"
        :key="index"
        :style="{
          marginRight: index + 1 === contentList?.length ? '0px' : '8px',
          background: currentIndex === index ? '#222222' : '#D8D8D8',
        }"
      ></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  ref,
  watch,
  defineEmits,
  computed,
  type ComputedRef,
  nextTick,
} from 'vue'
import { Marked } from 'marked'
import axios from 'axios'
import { addTargetForAnchor } from '@/utils/utils'
import {
  Carousel,
  CarouselContent,
  CarouselItem,
  type CarouselApi,
} from '@/components/ui/carousel'
import type { AssistantProps, TableListType } from '@/type'
import { isAndroid, isIos } from '@/config'

const props = defineProps<
  AssistantProps & {
    refresh: boolean
    currentAssistantKey: number
    AssistantList: AssistantProps[]
  }
>()
const currentIndex = ref<number>(0)
const compiledMarkdown = ref()
const marked = new Marked()
const markdown_ref = ref<HTMLElement>()
// 默认平台
const originalPlatform = isIos() ? 'iOS' : isAndroid() ? 'Android' : 'PC'
// 可用平台
const platformList: ComputedRef<string[]> = computed(() => {
  return Object.keys(props.tableList)
})
// 初始化选中平台
const platform = ref<keyof TableListType>(
  getDefaultAndSetPlatform(originalPlatform),
)

// 根据选中平台获取内容列表
const contentList = computed(() => {
  return props.tableList[platform.value] || []
})

const api = ref<CarouselApi>()

// 触摸相关状态
const touchStartX = ref(0)
const touchStartY = ref(0)
const touchEndX = ref(0)
const touchEndY = ref(0)
// 边界滑动检测状态
const isAtFirstPage = ref(false)
const isAtLastPage = ref(false)
const canTriggerChapterSwitch = ref(false)

// 触摸开始
function hdlTouchStart(event: TouchEvent) {
  const touch = event.touches[0]
  touchStartX.value = touch.clientX
  touchStartY.value = touch.clientY

  // 检查当前是否在边界页面
  if (contentList.value?.length > 1) {
    isAtFirstPage.value = currentIndex.value === 0
    isAtLastPage.value = currentIndex.value === contentList.value.length - 1
    canTriggerChapterSwitch.value = isAtFirstPage.value || isAtLastPage.value
  } else {
    // 单页内容总是可以触发章节切换
    canTriggerChapterSwitch.value = true
  }
}

// 触摸移动
function hdlTouchMove(event: TouchEvent) {
  // 如果不在边界页面或单页内容，不需要处理章节切换
  if (!canTriggerChapterSwitch.value) return

  // 对于多页内容在边界页面时，阻止默认行为以便检测边界滑动
  if (contentList.value?.length > 1 && canTriggerChapterSwitch.value) {
    const touch = event.touches[0]
    const deltaX = touch.clientX - touchStartX.value

    // 检测是否为向边界外的滑动
    if (
      (isAtFirstPage.value && deltaX > 20) ||
      (isAtLastPage.value && deltaX < -20)
    ) {
      event.preventDefault()
    }
  } else if (contentList.value?.length === 1) {
    // 单页内容阻止默认行为
    event.preventDefault()
  }
}

// 触摸结束
function hdlTouchEnd(event: TouchEvent) {
  // 只有在可以触发章节切换的情况下才处理
  if (!canTriggerChapterSwitch.value) {
    // 重置状态
    touchStartX.value = 0
    touchStartY.value = 0
    touchEndX.value = 0
    touchEndY.value = 0
    return
  }

  const touch = event.changedTouches[0]
  touchEndX.value = touch.clientX
  touchEndY.value = touch.clientY

  // 计算滑动距离
  const deltaX = touchEndX.value - touchStartX.value
  const deltaY = touchEndY.value - touchStartY.value

  // 设置最小滑动距离阈值
  const minSwipeDistance = 50

  // 判断是否为有效的水平滑动
  if (
    Math.abs(deltaX) > Math.abs(deltaY) &&
    Math.abs(deltaX) > minSwipeDistance
  ) {
    let shouldTriggerChapterSwitch = false

    if (contentList.value?.length === 1) {
      // 单页内容：任何滑动都触发章节切换
      shouldTriggerChapterSwitch = true
    } else if (contentList.value?.length > 1) {
      // 多页内容：只有在边界页面向边界外滑动才触发章节切换
      if (isAtFirstPage.value && deltaX > 0) {
        // 在第一页右滑
        shouldTriggerChapterSwitch = true
      } else if (isAtLastPage.value && deltaX < 0) {
        // 在最后一页左滑
        shouldTriggerChapterSwitch = true
      }
    }

    if (shouldTriggerChapterSwitch) {
      if (deltaX > 0) {
        // 右滑 - 触发上一章
        console.log('边界右滑触发上一章')
        // 边界处理：如果是第一章，跳到最后一章
        if (props.currentAssistantKey === 0) {
          currentIndex.value = 0
        }
        emit('update:hdlPrev')
      } else {
        // 左滑 - 触发下一章
        console.log('边界左滑触发下一章')
        // 边界处理：如果是最后一章，跳到第一章
        if (props.currentAssistantKey === props.AssistantList.length - 1) {
          currentIndex.value = 0
        }
        emit('update:hdlNext')
      }
      currentIndex.value = 0
    }
  }

  // 重置触摸坐标和状态
  touchStartX.value = 0
  touchStartY.value = 0
  touchEndX.value = 0
  touchEndY.value = 0
  isAtFirstPage.value = false
  isAtLastPage.value = false
  canTriggerChapterSwitch.value = false
}

function watchCurrentIndexChange() {
  watch(
    () => currentIndex.value,
    async (val: number) => {
      await changeMarkdown(val)
    },
    {
      immediate: true,
    },
  )
}

async function changeMarkdown(val: number) {
  try {
    const article = contentList.value?.[val]?.article
    const resp = await axios.get(article!)
    compiledMarkdown.value = addTargetForAnchor(await marked.parse(resp.data))
    setTimeout(() => {
      emit('update:mdAndImg')
    }, 800)
    if (markdown_ref.value) {
      markdown_ref.value.scrollTo({
        top: 0,
      })
    }
  } catch (error) {
    console.error('Error loading markdown file:', error)
  }
}
watchCurrentIndexChange()

const setApi = (val: CarouselApi) => {
  api.value = val
  val?.on('select', async () => {
    const previousIndex = api.value?.previousScrollSnap() as number
    const selectedIndex = api.value?.selectedScrollSnap() as number
    const lastIndex = (contentList.value?.length ?? 0) - 1
    currentIndex.value = selectedIndex
    console.log(
      'previousIndex, selectedIndex, lastIndex',
      previousIndex,
      selectedIndex,
      lastIndex,
      contentList.value,
      props.AssistantList.length - 1,
      props.currentAssistantKey,
    )

    // 轮播组件已禁用循环模式，只处理正常的页面切换
    // 章节切换统一通过触摸事件处理
    console.log('轮播页面切换：', previousIndex, '->', selectedIndex)
  })

  // 监听 reInit 事件，确保重新初始化后能正确处理新的配置
  val?.on('reInit', () => {
    console.log('carousel reInit triggered')
  })
}
const emit = defineEmits<{
  (event: 'update:platform', value: keyof TableListType): void
  (event: 'update:mdAndImg'): void
  (event: 'update:hdlNext'): void
  (event: 'update:hdlPrev'): void
}>()
// 平台计算
function getDefaultAndSetPlatform(plat: keyof TableListType) {
  const platCompute = (
    platformList.value.some((item) => item === plat)
      ? plat
      : platformList.value[0]
  ) as keyof TableListType
  return platCompute
}
// 切换平台
async function changePlatform(platVar: string): Promise<void> {
  const plat = platVar as keyof TableListType
  const oldLength = contentList.value?.length ?? 0

  // 重置当前索引
  currentIndex.value = 0

  // 设置新平台
  platform.value = getDefaultAndSetPlatform(plat)

  // 获取新平台的内容长度
  const newLength = props.tableList[platform.value]?.length ?? 0
  const needsCarouselRefresh = oldLength !== newLength

  if (needsCarouselRefresh) {
    console.log(
      'Content length changed, force refresh carousel',
      oldLength,
      '->',
      newLength,
    )
  }

  // 等待DOM更新完成后执行相关操作
  await nextTick()

  try {
    // 加载新的markdown内容
    await changeMarkdown(0)

    // 如果需要重新初始化轮播组件
    if (api.value) {
      api.value.reInit()
    }
  } catch (error) {
    console.error('Error during platform change:', error)
  }

  // 通知父组件平台已更改
  emit('update:platform', plat)
  // 通知父组件内容已更新（只触发一次）
  emit('update:mdAndImg')
}

watch(
  () => props.currentAssistantKey,
  () => {
    currentIndex.value = 0
    // 当切换助手时，重新选择合适的平台
    platform.value = getDefaultAndSetPlatform(originalPlatform)
  },
)

// 监听平台变化，重新加载markdown（仅在初始化时执行）
watch(
  () => platform.value,
  async () => {
    // 只在初始化时执行，避免与 changePlatform 方法冲突
    if (!api.value) {
      currentIndex.value = 0
      await nextTick()
      try {
        await changeMarkdown(0)
      } catch (error) {
        console.error('Error loading initial markdown:', error)
      }
    }
  },
  { immediate: true },
)

// 监听内容列表变化，重新初始化轮播组件
watch(
  () => contentList.value?.length,
  (newLength, oldLength) => {
    if (api.value && newLength !== oldLength) {
      console.log(
        'contentList length changed, reInit carousel',
        newLength,
        oldLength,
      )
      // 使用 nextTick 确保 DOM 更新后再重新初始化
      nextTick(() => {
        api.value?.reInit()
      })
    }
  },
)

// 暴露changePlatform函数供父组件调用
defineExpose({
  changePlatform,
})
</script>

<style lang="scss" scoped>
.pic-wrap {
  padding: 10px;
}

.pic {
  filter: drop-shadow(1px 2px 4px hsl(0, 0%, 60.8%));
  border-radius: 5px;
}
</style>
